优化 Unity 渲染

渲染介绍

在最基本的层面上,渲染可以描述如下:

现在让我们仔细看看会发生什么。我们将在后面的文章中更详细地介绍这些步骤中的每一个步骤,但现在,我们只是熟悉使用的单词,并了解CPU和GPU在渲染中的不同作用

经常用来描述渲染的短语是渲染管道,这是一个很有用的形象,要记住,高效的渲染就是要保持信息的流动

每渲染一帧,CPU就会做以下工作:

对于每一个包含绘图调用的批次,CPU现在必须做以下工作:

同时,GPU会做以下工作:

渲染问题的类型

关于渲染,最重要的一点是:CPU和GPU都必须完成所有的任务才能渲染画面。如果其中任何一个任务完成的时间过长,都会导致帧的渲染延迟

渲染问题有两种基本原因。第一类问题是由低效的管道引起的。当渲染管道中的一个或多个步骤需要太长的时间才能完成,从而中断了数据的顺利流动时,就会出现低效管道。管道内的低效被称为瓶颈。第二种类型的问题是由简单地试图通过管道推送太多数据引起的。即使是最高效的流水线也有一个极限,它在一帧中能处理多少数据

当我们的游戏因为CPU执行渲染任务的时间过长而导致渲染一帧的时间过长时,我们的游戏就是所谓的CPU绑定。当我们的游戏因为GPU执行渲染任务的时间过长而导致渲染一帧的时间过长时,我们的游戏就是所谓的GPU绑定

如果我们的游戏是和CPU绑定的

大致来说,为了渲染一帧画面,必须由CPU完成的工作分为三类

这些大类包含了许多单独的任务,这些任务可以在多个线程中进行。线程允许单独的任务同时发生;当一个线程执行一个任务时,另一个线程可以执行一个完全独立的任务。这意味着可以更快地完成工作。当渲染任务被分割在不同的线程上时,这被称为多线程渲染

在Unity的渲染过程中,有三种线程参与:主线程、渲染线程和工作线程。主线程是我们游戏的大部分CPU任务发生的地方,包括一些渲染任务。渲染线程是一个专门向GPU发送命令的线程。工作线程每个线程都会执行一个任务,比如剔除或网格换肤。哪些任务由哪个线程执行取决于我们游戏的设置和游戏运行的硬件。例如,我们的目标硬件拥有的CPU核数越多,可以催生的工作线程就越多。出于这个原因,在目标硬件上对我们的游戏进行配置是非常重要的;我们的游戏在不同的设备上可能会有非常不同的表现

因为多线程渲染是复杂的,而且依赖于硬件,所以我们在试图提高性能之前,必须了解哪些任务导致我们的游戏被CPU束缚。如果我们的游戏运行得很慢,是因为在一个线程上进行裁剪操作耗时过长,那么我们在另一个线程上减少向GPU发送命令所需的时间是没有帮助的

并不是所有的平台都支持多线程渲染,在撰写本文时,WebGL并不支持这一功能。在不支持多线程渲染的平台上,所有的CPU任务都在同一个线程上执行。如果我们在这样的平台上受到CPU的约束,优化任何CPU工作都会提高CPU性能。如果我们的游戏是这种情况,我们应该阅读下面所有的章节,并考虑哪些优化可能最适合我们的游戏